package com.ht.pms.core.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ht.pms.core.common.constant.SalaryConstants;
import com.ht.pms.core.common.constant.TemplateEnum;
import com.ht.pms.core.dao.SalarySheetManagementDao;
import com.ht.pms.core.dao.SalaryUserDao;
import com.ht.pms.core.dto.Result;
import com.ht.pms.core.dto.ReturnCodeEnum;
import com.ht.pms.core.dto.SalarySheetQueryReq;
import com.ht.pms.core.dto.UpdateSalaryReq;
import com.ht.pms.core.dto.dict.DictParamsDto;
import com.ht.pms.core.dto.upload.UploadFile;
import com.ht.pms.core.dto.user.UserInfoDto;
import com.ht.pms.core.service.SalarySheetManagementService;

/**
 * @author:喻尊龙
 * @date: 2018/4/13
 */
@Service
public class SalarySheetManagementServiceImpl implements SalarySheetManagementService {

    @Autowired
    private SalarySheetManagementDao salarySheetManagementDao;

    @Autowired
    private SalaryUserDao salaryUserDao;

    @Override
    public List<Map<String, String>> getSalaryTableColum(String templateCode, String queryType, String batchCode)
            throws Exception {
        List<Map<String, Object>> columList = salarySheetManagementDao.getSalaryColum(templateCode);

        List<Map<String, String>> mapList = new ArrayList<>();
        Map<String, String> columFist = new HashMap<>();
        columFist.put("type", "checkbox");
        columFist.put("fixed", "left");
        mapList.add(columFist);

        String width = "140";
        String edit = "text";

        UploadFile file = salarySheetManagementDao.getUploadFileByBatchCode(batchCode);
        if (file != null && "1".equals(file.getFinalState())) {
            edit = "false";
        }

        if (!queryType.equals("2")) {
            Map<String, String> colum1 = new HashMap<>();
            colum1.put("field", "inState");
            colum1.put("title", "是否有效");
            colum1.put("align", "center");
            colum1.put("width", width);
            colum1.put("fixed", "left");
            colum1.put("templet", "#inSateTpl");
            mapList.add(colum1);
        }

        if (columList != null) {
            for (Map<String, Object> columMap : columList) {
                if ("工号".equals(columMap.get("dict_name") + "") || "序号".equals(columMap.get("dict_name") + "")) {
                    Map<String, String> colum = new HashMap<>();
                    colum.put("field", columMap.get("dict_code") + "");
                    colum.put("title", columMap.get("dict_name") + "");
                    colum.put("align", "center");
                    colum.put("width", width);
                    colum.put("fixed", "left");
                    mapList.add(colum);

                } else {
                    Map<String, String> colum = new HashMap<>();
                    colum.put("field", columMap.get("dict_code") + "");
                    colum.put("title", columMap.get("dict_name") + "");
                    colum.put("align", "center");
                    colum.put("width", width);
                    colum.put("edit", edit);
                    mapList.add(colum);
                }
            }
        }
        // 已审核的数据，薪资和考勤模板内容才有发送状态和确认状态
        if (queryType.equals("2") && (templateCode.equals(TemplateEnum.TEMP_KQ.getCode())
                || templateCode.equals(TemplateEnum.TEMP_XZ.getCode()))) {
            Map<String, String> columLeft1 = new HashMap<>();
            columLeft1.put("field", "sendState");
            columLeft1.put("fixed", "right");
            columLeft1.put("title", "邮件状态");
            columLeft1.put("width", width);
            columLeft1.put("align", "center");
            columLeft1.put("templet", "#sendStateTpl");
            mapList.add(columLeft1);
            Map<String, String> columLeft2 = new HashMap<>();
            columLeft2.put("field", "ddState");
            columLeft2.put("fixed", "right");
            columLeft2.put("title", "钉钉状态");
            columLeft2.put("width", width);
            columLeft2.put("align", "center");
            columLeft2.put("templet", "#ddStateTpl");
            mapList.add(columLeft2);

        }

        Map<String, String> columEnd = new HashMap<>();
        columEnd.put("fixed", "right");
        columEnd.put("title", "操作");
        columEnd.put("width", "220");
        columEnd.put("align", "center");
        columEnd.put("toolbar", "#barTools");
        mapList.add(columEnd);

        return mapList;

    }

    @Override
    public List<Map<String, Object>> getSalaryTableData(String dataSql) throws Exception {

        return salarySheetManagementDao.getData(dataSql);
    }

    @Override
    public int getSalaryTableDataCount(String countSql) throws Exception {
        Map<String, Object> countMap = salarySheetManagementDao.getCount(countSql);
        int count = 0;
        if (countMap != null) {
            count = Integer.parseInt(countMap.get("count") + "");
        }
        return count;
    }

    @Override
    public Map<String, String> getSalaryTableDataSql(SalarySheetQueryReq request) throws Exception {

        Map<String, String> sqlMap = new HashMap<>();
        String templateCode = request.getTemplateCode();
        // 查询所需要的列名和表名
        List<Map<String, Object>> salaryColums = salarySheetManagementDao.getSalaryColum(templateCode);
        List<Map<String, Object>> salaryTableNames = salarySheetManagementDao.getSalaryTableName(templateCode);

        StringBuilder selectColumn = new StringBuilder();
        StringBuilder selectTables = new StringBuilder();

        if (salaryColums != null && salaryColums.size() > 0) {
            for (int i = 0; i < salaryColums.size(); i++) {
                Map<String, Object> map = salaryColums.get(i);
                String column = map.get("dict_column") + "";
                String tableName = map.get("dict_table_name") + "";
                String columnNameAlias = map.get("dict_code") + "";
                String tableNameAlias = tableName.substring(tableName.length() - 1);
                if (StringUtils.isNotBlank(column) && StringUtils.isNotBlank(tableName)) {
                    if (i == salaryColums.size() - 1) {

                        selectColumn.append(tableNameAlias + "." + column + " as " + columnNameAlias);
                    } else {
                        if (i == 0) {
                            selectColumn.append(tableNameAlias + ".file_id as file_id, " + tableNameAlias
                                    + ".job_code as job_code, " + tableNameAlias + ".batch_code as batch_code, "
                                    + tableNameAlias + ".final_state as finalState, " + tableNameAlias
                                    + ".in_state as inState," );
                            if (TemplateEnum.TEMP_KQ.getCode().equals(templateCode) || TemplateEnum.TEMP_XZ.getCode().equals(templateCode)) {
                                selectColumn.append( tableNameAlias+".send_state as sendState, " + tableNameAlias + ".dd_state as ddState, ");
                            }
                        }
                        selectColumn.append(tableNameAlias + "." + column + " as " + columnNameAlias + " ,");
                    }
                }
            }
        } else {
            throw new Exception("未获取到列名数据");
        }

        String currentTableName = "";
        String lastTableName = "";
        String currentTableNameAlias = "";
        String lastTableNameAlias = "";

        if (salaryTableNames != null && salaryTableNames.size() > 0) {

            for (int i = 0; i < salaryTableNames.size(); i++) {
                Map<String, Object> tables = salaryTableNames.get(i);
                currentTableName = tables.get("tableName") + "";
                if (i == 0) {
                    currentTableNameAlias = currentTableName.substring(currentTableName.length() - 1);
                    selectTables.append(currentTableName + " as " + currentTableNameAlias);
                    lastTableName = currentTableName;
                    lastTableNameAlias = lastTableName.substring(lastTableName.length() - 1);
                } else {
                    currentTableNameAlias = currentTableName.substring(currentTableName.length() - 1);
                    lastTableNameAlias = lastTableName.substring(lastTableName.length() - 1);
                    selectTables.append(" inner join " + currentTableName + " as " + currentTableNameAlias + " on "
                            + currentTableNameAlias + ".job_code = " + lastTableNameAlias + ".job_code and "
                            + currentTableNameAlias + ".file_id=" + lastTableNameAlias + ".file_id");
                    lastTableName = currentTableName;
                }

            }
        } else {
            throw new Exception("未获取到数据表名");
        }

        selectTables.append(" INNER join t_upload_file as t1 ON " + lastTableNameAlias
                + ".batch_code = t1.batch_code AND " + lastTableNameAlias
                + ".file_id=t1.file_id ");


        String dataSql = "select " + selectColumn.toString() + " from " + selectTables.toString();

        String condition = "";

        if ("1".equals(request.getQueryType())) {
            // 导入查询
            condition = " where 1=1 " + " AND " + lastTableNameAlias + ".file_id in (" + request.getFileId() + ")";

        } else {
            // 数据管理查询
            condition = " where 1=1 " + " AND " + lastTableNameAlias + ".in_state = 1 and " + lastTableNameAlias + ".audit_state = 1 and t1.is_del=0 and t1.state = 1 " +
                    "and " + lastTableNameAlias + ".batch_code='" + request.getBatchCode() + "'";
        }

        if (StringUtils.isNotBlank(request.getInState())) {
            condition = condition + " AND " + lastTableNameAlias + ".in_state='" + request.getInState() + "'";
        }
        if (StringUtils.isNotBlank(request.getKeyworld())) {
            condition = condition + " AND (" + lastTableNameAlias + ".job_code like '%" + request.getKeyworld()
                    + "%' OR " + lastTableNameAlias + ".column3 like '%" + request.getKeyworld() + "%') ";
        }
        String sqlCount = "select count(*) as count from " + selectTables.toString() + condition;
        dataSql = dataSql + condition + " ORDER BY " + lastTableNameAlias + ".in_state asc," + lastTableNameAlias
                + ".column1  LIMIT " + ((request.getPage() - 1) * request.getLimit()) + "," + request.getLimit() + "";

        System.out.println("==========拼接的dataSql:" + dataSql);
        System.out.println("==========拼接的sqlCount:" + dataSql);
        sqlMap.put("dataSql", dataSql);
        sqlMap.put("countSql", sqlCount);

        return sqlMap;
    }

    /**
     * 更新薪资表数据
     *
     * @param req
     * @return
     * @throws Exception
     */
    @Override
    public Result updateSalaryData(UpdateSalaryReq req) throws Exception {

        Result result = Result.buildSuccess();

        // 查询字段属性信息
        DictParamsDto dictParamsDto = null;
        if (StringUtils.isNotBlank(req.getFieldName())) {
            dictParamsDto = salarySheetManagementDao.getDictParamsDto(req.getFieldName());
        } else {
            result = Result.buildFail().msg("未获取到列名");
            return result;
        }
        if (dictParamsDto != null) {
            int fieldType = dictParamsDto.getDictDataType();
            String fieldValue = req.getValue();
            boolean match = true;
            boolean length = true;
            switch (fieldType) {
                case 1:// 整形
                    String intRegex = "^\\d+$";
                    match = fieldValue.matches(intRegex);
                    if (fieldValue.length() > 10) {
                        length = false;
                    }
                    break;
                case 2:// 字符串
                    if (fieldValue.length() > 45) {
                        length = false;
                    }
                    break;
                case 3:// 浮点
                    String floatRegex = "^\\d+(\\.\\d+)?$";
                    match = fieldValue.matches(floatRegex);
                    if (fieldValue.length() > 13) {
                        length = false;
                    }
                    break;
                case 4:// 日期
                    String dataRegex = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$";
                    match = fieldValue.matches(dataRegex);
                    break;
                default:
            }
            if (!match) {
                result = Result.buildFail().msg("请输入正确的数据类型");
                return result;
            }
            if (!length) {
                result = Result.buildFail().msg("字段超长");
                return result;
            }
            req.setTableName(dictParamsDto.getDictTableName());
            req.setFieldName(dictParamsDto.getDictColumn());
            int count = salarySheetManagementDao.updateSalaryData(req);
            if (count <= 0) {
                result = Result.buildFail().msg("更新失败");
                return result;
            }
        } else {
            result = Result.buildFail().msg("未查询到此数据列");
            return result;
        }
        return result;
    }

    public static void main(String[] args) {
        String queryType = "1";
        String templateCode = "MB20180427";
        boolean flag = queryType.equals("1") && (templateCode.equals(TemplateEnum.TEMP_KQ.getCode())
                || templateCode.equals(TemplateEnum.TEMP_XZ.getCode()));
        System.out.println(flag);
    }

    @Override
    public Result validateUpdataSalary(UpdateSalaryReq req) {
        // 查询字段属性信息
        DictParamsDto dictParamsDto = null;
        if (StringUtils.isNotBlank(req.getFieldName())) {
            dictParamsDto = salarySheetManagementDao.getDictParamsDto(req.getFieldName());
        } else {
            return Result.buildFail().msg("未获取到列名");
        }
        if (dictParamsDto != null) {
            Result<Integer> result = new Result<>();
            result.setReturnCode(ReturnCodeEnum.EXCEL_RESULT.getReturnCode());
            // 查询修改项是否是姓名，工号，邮箱
            String dictName = dictParamsDto.getDictName();

            UserInfoDto userInfo = salaryUserDao.queryUserInfoByJobCode(req.getJobCode());
            if (userInfo == null) {
                // 证明 该行的用户信息不存在，不作处理
                return Result.buildSuccess();
            }

            switch (dictName) {
                case SalaryConstants.SALARY_JOB_CODE_NAME: // 工号
                    return Result.buildFail().msg("工号不能修改，请删除记录重新导入！");
                case SalaryConstants.SALARY_EMAIL_NAME: // 邮箱
                    if (!userInfo.getEmail().equals(req.getValue())) {
                        result.setMsg("该邮箱与数据库不一致，是否确认修改？");
                        return result;
                    }
                    break;
                case SalaryConstants.SALARY_USER_NAME: // 姓名
                    if (!userInfo.getUserName().equals(req.getValue())) {
                        result.setMsg("该姓名与数据库不一致，是否确认修改？");
                        return result;
                    }
                    break;
                default:
                    break;
            }
        } else {
            return Result.buildFail().msg("未查询到此数据列");
        }
        return Result.buildSuccess();
    }

    @Override
    public List<Map<String, Object>> getPmsListSendData(String tableName, String batchCode) {
        return salarySheetManagementDao.getPmsListSendData(tableName, batchCode);
    }

    @Override
    public int countPmsListSendData(String tableName, String batchCode) {
        return salarySheetManagementDao.countPmsListSendData(tableName, batchCode);
    }


}
